package middol.utils

import grails.async.Promise
import grails.plugin.springsecurity.SpringSecurityService
import grails.util.Holders
import groovy.util.logging.Slf4j
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource
import org.springframework.jdbc.core.namedparam.SqlParameterSource

import static grails.async.Promises.task

@Slf4j
class SaveOperationLog {

    def saveEntity(def entity, String type) {
        if (entity) {
            saveSQLCore(entity?.toString(), type, null)
        }
    }
    /**
     * 增删改操作
     * @param sql
     * @param source
     * @return
     */
    def saveSQL(String sql, SqlParameterSource source) {
        String type = "INSERT"
        String temp = sql?.toUpperCase()
        if (temp?.contains("INSERT")) {
            type = "INSERT"
        }
        if (temp?.contains("DELETE")) {
            type = "DELETE"
        }
        if (temp?.contains("UPDATE")) {
            type = "UPDATE"
        }
        saveSQLCore(sql, type, source)
    }

    /**
     * 执行sql
     * @param sql
     * @param type
     * @param source
     * @return
     */
    def saveSQLCore(String sql, String type, MapSqlParameterSource source) {
        if (sql) {
            DataBaseService dataBaseService = Holders.grailsApplication.mainContext.getBean(DataBaseService.class)
            SpringSecurityService springSecurityService = Holders.grailsApplication.mainContext.getBean(SpringSecurityService.class)
            String currentUserId = springSecurityService.currentUserId
            Promise p = task {
                def userID = currentUserId
                String uuid = UUID.randomUUID().toString()
                String inserSQL = """insert into TSYS_OPERATIONRECORD t
                                      (t.operation_id,
                                       t.operation_userid,
                                       t.operation_sql,
                                       t.operation_date,
                                       t.operation_description,
                                       t.operation_type)
                                    values
                                      (:operation_id,
                                       :operation_userid,
                                       :operation_sql,
                                       sysdate,
                                       '',
                                       :operation_type)"""
                MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource()
                mapSqlParameterSource.addValue("operation_id", uuid)
                mapSqlParameterSource.addValue("operation_userid", userID)
                String data = sql
                if (source) {
                    data += "/" + source.getValues()?.toString()
                }
                mapSqlParameterSource.addValue("operation_sql", data)
                mapSqlParameterSource.addValue("operation_type", type)
                try {
                    dataBaseService.update(inserSQL, mapSqlParameterSource)
                } catch (e) {
                    e.printStackTrace()
                }
                return mapSqlParameterSource?.values
            }
            p.onError { Throwable err ->
                log.info("An error occured ${err.message}")
            }
            p.onComplete { result ->
                log.info("日志保存 $result?.toString()")
            }
        }
    }
}
